package com.jevons.geo_lib.geojson.adapter;

import androidx.annotation.Keep;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.mapbox.geojson.BoundingBox;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.GeometryCollection;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.MultiLineString;
import com.mapbox.geojson.MultiPoint;
import com.mapbox.geojson.MultiPolygon;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;

/**
 * Copyright 2020 JxGIS
 *
 * @file GeoJsonAdapterFactory
 * @auth linaisheng
 * Created on 2022/7/13.
 * Description：
 */
@Keep
public abstract class GeoJsonAdapterFactory implements TypeAdapterFactory {

    /**
     * Create a new instance of this GeoJson type adapter factory, this is passed into the Gson
     * Builder.
     *
     * @return a new GSON TypeAdapterFactory
     * @since 3.0.0
     */
    public static TypeAdapterFactory create() {
        return new GeoJsonAdapterFactoryIml();
    }

    /**
     * GeoJsonAdapterFactory implementation.
     *
     * @since 3.0.0
     */
    public static final class GeoJsonAdapterFactoryIml extends GeoJsonAdapterFactory {
        @Override
        @SuppressWarnings("unchecked")
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            Class<?> rawType = type.getRawType();
            if (BoundingBox.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) BoundingBox.typeAdapter(gson);
            } else if (Feature.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new FeatureTypeAdapter(gson);
            } else if (FeatureCollection.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new FeatureCollectionTypeAdapter(gson);
            } else if (GeometryCollection.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new GeometryCollectionTypeAdapter(gson);
            } else if (LineString.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new LineStringTypeAdapter(gson);
            } else if (MultiLineString.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new MultiLineStringTypeAdapter(gson);
            } else if (MultiPoint.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new MultiPointTypeAdapter(gson);
            } else if (MultiPolygon.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new MultiPolygonTypeAdapter(gson);
            } else if (Polygon.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new PolygonTypeAdapter(gson);
            } else if (Point.class.isAssignableFrom(rawType)) {
                return (TypeAdapter<T>) new PointTypeAdapter(gson);
            }
            return null;
        }
    }
}

